import pytest
from typing import Dict, Any
from unittest.mock import Mock, patch

from app.schemas.user import UserCreate, UserUpdate
from tests.api.enhanced_api_test import EnhancedAPITest
from tests.factories.test_data_factory import (
    create_user_create_data,
    create_user_update_data
)
from tests.utils import (
    assert_response_status,
    assert_response_data
)


class TestUserAPI(EnhancedAPITest):
    """用户API测试类"""
    
    def setup_method(self):
        """测试前准备"""
        super().setup_method()
        
        # 创建测试用户数据
        self.test_user_data = create_user_create_data().dict()
        self.test_update_data = create_user_update_data().dict()
    
    @patch('app.api.v1.endpoints.users.UserService')
    @patch('app.api.deps.get_current_active_user')
    @patch('app.api.deps.get_db')
    def test_create_user_api_success(self, mock_get_db, mock_get_current_user, mock_user_service_class):
        """测试创建用户成功"""
        # 模拟依赖
        mock_get_db.return_value = self.mock_db
        mock_get_current_user.return_value = self.mock_current_user
        mock_user_service = Mock()
        mock_user_service_class.return_value = mock_user_service
        
        # 模拟服务返回
        mock_created_user = Mock()
        mock_created_user.id = 1
        mock_created_user.username = self.test_user_data["username"]
        mock_created_user.email = self.test_user_data["email"]
        mock_created_user.full_name = self.test_user_data["full_name"]
        mock_created_user.is_active = self.test_user_data["is_active"]
        
        mock_user_service.create_user.return_value = mock_created_user
        
        # 执行测试
        response_data = self.test_create_user_success(self.test_user_data)
        
        # 验证结果
        assert "id" in response_data
        assert response_data["username"] == self.test_user_data["username"]
        assert response_data["email"] == self.test_user_data["email"]
        
        # 验证服务调用
        mock_user_service.create_user.assert_called_once()
    
    @patch('app.api.v1.endpoints.users.UserService')
    @patch('app.api.deps.get_current_active_user')
    @patch('app.api.deps.get_db')
    def test_get_users_list_api(self, mock_get_db, mock_get_current_user, mock_user_service_class):
        """测试获取用户列表"""
        # 模拟依赖
        mock_get_db.return_value = self.mock_db
        mock_get_current_user.return_value = self.mock_current_user
        mock_user_service = Mock()
        mock_user_service_class.return_value = mock_user_service
        
        # 模拟服务返回
        mock_users = []
        for i in range(3):
            mock_user = Mock()
            mock_user.id = i + 1
            mock_user.username = f"user{i+1}"
            mock_user.email = f"user{i+1}@example.com"
            mock_users.append(mock_user)
        
        mock_user_service.get_users.return_value = (mock_users, len(mock_users))
        
        # 执行测试
        response_data = self.test_get_users_list()
        
        # 验证结果
        assert "items" in response_data
        assert "total" in response_data
        assert len(response_data["items"]) == 3
        assert response_data["total"] == 3
        
        # 验证服务调用
        mock_user_service.get_users.assert_called_once()
    
    @patch('app.api.v1.endpoints.users.UserService')
    @patch('app.api.deps.get_current_active_user')
    @patch('app.api.deps.get_db')
    def test_get_user_by_id_api(self, mock_get_db, mock_get_current_user, mock_user_service_class):
        """测试根据ID获取用户"""
        # 模拟依赖
        mock_get_db.return_value = self.mock_db
        mock_get_current_user.return_value = self.mock_current_user
        mock_user_service = Mock()
        mock_user_service_class.return_value = mock_user_service
        
        # 模拟服务返回
        mock_user = Mock()
        mock_user.id = 1
        mock_user.username = "testuser"
        mock_user.email = "test@example.com"
        mock_user.full_name = "Test User"
        
        mock_user_service.get_user.return_value = mock_user
        
        # 执行测试
        response_data = self.test_get_user_by_id(1)
        
        # 验证结果
        assert response_data["id"] == 1
        assert response_data["username"] == "testuser"
        
        # 验证服务调用
        mock_user_service.get_user.assert_called_once_with(1)
    
    @patch('app.api.v1.endpoints.users.UserService')
    @patch('app.api.deps.get_current_active_user')
    @patch('app.api.deps.get_db')
    def test_update_user_api_success(self, mock_get_db, mock_get_current_user, mock_user_service_class):
        """测试更新用户成功"""
        # 模拟依赖
        mock_get_db.return_value = self.mock_db
        mock_get_current_user.return_value = self.mock_current_user
        mock_user_service = Mock()
        mock_user_service_class.return_value = mock_user_service
        
        # 模拟服务返回
        mock_updated_user = Mock()
        mock_updated_user.id = 1
        mock_updated_user.username = "testuser"
        mock_updated_user.email = "test@example.com"
        mock_updated_user.full_name = self.test_update_data["full_name"]
        mock_updated_user.phone = self.test_update_data["phone"]
        
        mock_user_service.update_user.return_value = mock_updated_user
        
        # 执行测试
        response_data = self.test_update_user_success(1, self.test_update_data)
        
        # 验证结果
        assert response_data["id"] == 1
        assert response_data["full_name"] == self.test_update_data["full_name"]
        assert response_data["phone"] == self.test_update_data["phone"]
        
        # 验证服务调用
        mock_user_service.update_user.assert_called_once_with(1, UserUpdate(**self.test_update_data))
    
    @patch('app.api.v1.endpoints.users.UserService')
    @patch('app.api.deps.get_current_active_user')
    @patch('app.api.deps.get_db')
    def test_delete_user_api_success(self, mock_get_db, mock_get_current_user, mock_user_service_class):
        """测试删除用户成功"""
        # 模拟依赖
        mock_get_db.return_value = self.mock_db
        mock_get_current_user.return_value = self.mock_current_user
        mock_user_service = Mock()
        mock_user_service_class.return_value = mock_user_service
        
        # 模拟服务返回
        mock_user_service.delete_user.return_value = True
        
        # 执行测试
        response_data = self.test_delete_user_success(1)
        
        # 验证结果
        assert "message" in response_data
        
        # 验证服务调用
        mock_user_service.delete_user.assert_called_once_with(1)


if __name__ == "__main__":
    pytest.main([__file__, "-v"])